using UnityEngine;
using System.Collections;

/// \class  gkScrollingInfo
/// \brief  Info on the current world scrolling
[AddComponentMenu("GK/Engine/Game/Scrolling/gkScrollingInfo")]
[RequireComponent (typeof (gkVelocityController))]
[RequireComponent (typeof (gkPhysicComponent))]
[RequireComponent (typeof (gkBoostComponent))]
public class gkScrollingInfo : MonoBehaviour 
{
    /// The default scrolling velocity
    public float ScrollingVelocityDefault = 4.0f;

    /// The minimum scrolling velocity
    public float ScrollingVelocityMin = 2.0f;

    /// The maximum scrolling velocity
    public float ScrollingVelocityMax = 14.0f;

    /// The scrolling total movement
    private Vector3 m_f3ScrollingTotalMovement;

    /// The scrolling normal velocity
    private Vector3 m_f3ScrollingNormalVelocity;

    ///  Is the scrolling accelerated (i.e. at a greater velocity that the normal)
    private bool m_bIsAccelerated;

    /// The Velocity controller
    private gkVelocityController m_rVelocityController;

    /// The physic component
    private gkPhysicComponent m_rPhysicComponent;

    /// The boost component
    private gkBoostComponent m_rBoostComponent;

    /// \brief  Get actual percentage of the scrolling velocity max
    public float GetScrollingVelocityPercentage()
    {
	    return (-m_rPhysicComponent.GetLinearVelocity().x - ScrollingVelocityMin)/(ScrollingVelocityMax - ScrollingVelocityMin);
    }

    /// \brief  Get actual percentage of the scrolling velocity max
    public float GetScrollingVelocity()
    {
	    return m_rPhysicComponent.GetLinearVelocity().x;
    }

    /// \brief  Is the scrolling accelerated (i.e. at a greater velocity that the normal)
    public bool IsAccelerated()
    {
	    return m_bIsAccelerated;
    }

    /// \brief  Get the scrolling velocity
    public Vector3 GetScrollingTotalMovement()
    {
	    return m_f3ScrollingTotalMovement;
    }

    /// \brief  Boost the velocity during a specified time
    /// \param[in]  a_fBoostDuration :
    ///             If < 0  : Infinite
    /// \param[in]  a_fReachVelocityDuration : 
    ///             If < 0  : Keep the default acceleration
    ///             If == 0 : Reach the desired velocity immediately 
    public void Boost(float a_fVelocityMaxPercent, float a_fBoostDuration, float a_fReachVelocityDuration = -1)
    {
	    Vector3 f3BoostVelocity = Vector3.zero;
    	
	    // Compute the boost velocity via the percentage of the max velocity
	    f3BoostVelocity.x = -(a_fVelocityMaxPercent*(ScrollingVelocityMax - ScrollingVelocityMin) + ScrollingVelocityMin);
    	
	    // Is the scrolling accelerated or decelerated
	    if(Mathf.Abs(f3BoostVelocity.x) > ScrollingVelocityDefault)
	    {
		    m_bIsAccelerated = true;
	    }
	    else
	    {
		    m_bIsAccelerated = false;
	    }

	    // Apply Boost
	    m_rBoostComponent.Boost(m_f3ScrollingNormalVelocity, f3BoostVelocity, 
		    a_fBoostDuration, a_fReachVelocityDuration, a_fReachVelocityDuration);
    }
	
	
	/// \brief  Boost the velocity during a specified time
    public void StopBoost(float a_fBlendToStopTime = 0.0f)
    {
		Boost(ScrollingVelocityDefault, 0.0f, a_fBlendToStopTime);
	}

    /// \brief  Called just after the game begin to play
    void Start()
    {
        // Get the velocity controller
        m_rVelocityController = GetComponent<gkVelocityController>();

        // Get the physic component
        m_rPhysicComponent = GetComponent<gkPhysicComponent>();

        // Get the boost component
        m_rBoostComponent = GetComponent<gkBoostComponent>();

	    // Set the desired velocity
	    m_f3ScrollingNormalVelocity.x = -ScrollingVelocityDefault;
	    m_rVelocityController.SetDesiredVelocity(m_f3ScrollingNormalVelocity, -1.0f);
    }

    /// \brief  Called each frame
    void LateUpdate()
    {
	    m_f3ScrollingTotalMovement += m_rPhysicComponent.GetLinearVelocity() * Time.deltaTime;
    }
}

